home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 October: Mac OS SDK / Dev.CD Oct 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / Sample Code / Graphics Samples / Offscreen Animation ƒ / Offscreen Animation.c next >
Encoding:
C/C++ Source or Header  |  1996-04-15  |  12.2 KB  |  477 lines  |  [TEXT/KAHL]

  1. /****************************************************************************/
  2. /*                                                                            */
  3. /*    Application:    Offscreen Animation                                        */
  4. /*                                                                            */
  5. /*    Description:    This sample shows how to use the QuickDraw™ GX          */
  6. /*                    offscreenlibrary to perform simple animation.            */
  7. /*                                                                            */
  8. /*    Files:            Offscreen Animation.π                                    */
  9. /*                    Offscreen Animation.c                                    */
  10. /*                                                                            */
  11. /*    Programmer:        Edgar Lee                                                */
  12. /*    Organization:    Apple Computer, Inc.                                    */
  13. /*    Department:        Developer Technical Support, DTS                        */
  14. /*    Language:        C (Think C version 6.0)                                    */
  15. /*    Recompiled:        Think C version 7.0.6                                    */
  16. /*    Date Created:    12-13-92                                                */
  17. /*                                                                            */
  18. /*    Change History: 9/93: Updated to run with QuickDraw GX ß2 "GXified"        */
  19. /*                          interface files    - PLA                            */
  20. /*                                                                            */
  21. /*                    4/96:    Updated #includes to support changed GX Library    */
  22. /*                            names.                                            */
  23. /*                            Recompiled by unchecking Compiler Option -        */
  24. /*                            "Generate 68881 instructions", this allows it    */
  25. /*                            to run on CPUs without a FPU.                    */
  26. /*                            Changed fixed to Fixed.                            */
  27. /*                            Added the copyright info. - BOB                    */
  28. /*                                                                            */
  29. /*                                                                            */
  30. /*        ©1992 - 1996 Apple Computer Inc. All Rights reserved.                */
  31. /*                                                                            */
  32. /****************************************************************************/
  33.  
  34. #include <Desk.h>
  35. #include <Events.h>
  36. #include <Fonts.h>
  37. #include <Windows.h>
  38. #include <Memory.h>
  39. #include <ToolUtils.h>
  40. #include <OSEvents.h>
  41. #include <Quickdraw.h>
  42.  
  43. #include <GXEnvironment.h>
  44. #include <GXGraphics.h>
  45. #include "GraphicsLibraries.h"
  46. #include <GXErrors.h>
  47. #include "QDLibrary.h"
  48. #include "OffscreenLibrary.h"
  49.  
  50. /*-----------------------------------------------------------------------------------*/
  51.  
  52. /*************************/
  53. /* Constant Declarations */
  54. /*************************/
  55.  
  56. #define    kWinWidth        400        /* The window width. */
  57. #define    kWinHeight        300        /* The window height. */
  58.  
  59. #define kWinLeft        (((qd.screenBits.bounds.right - qd.screenBits.bounds.left) - kWinWidth) / 2)
  60. #define kWinTop            (((qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) - kWinHeight) / 2)
  61.  
  62. #define    kMaxObjects        100        /* Total moving objects in offscreen. */
  63.  
  64. typedef    struct {
  65.     gxShape    shape;
  66.     int        xdelta;
  67.     int        ydelta;
  68. } movingObjectType;
  69.  
  70. /*******************************/
  71. /* Global Variable Definitions */
  72. /*******************************/
  73.  
  74. WindowPtr            gWindow;                        /* The cgrafport. */
  75. offscreen            gOffscreen;
  76.  
  77. gxShape                gTheBackground;                    /* The offscreen background. */
  78. movingObjectType    gMovingObject[kMaxObjects];        /* The moving offscreen objects. */
  79.  
  80. void    initMac(void);                                /* Initializes the mac. */
  81. void    createWindow(void);                            /* Initializes the window's cgrafport. */
  82. void    doEventLoop(void);                            /* Handles events. */
  83.  
  84. void    createOffscreen(void);                        /* Creates a GX offscreen. */
  85. void    initializeShapes(void);                        /* Initializes the shapes used in the offscreen. */
  86. void    updateOffscreen(void);                        /* Updates the position of the moving shapes. */
  87. void    drawOffscreen(void);                        /* Draw the offscreen to the window. */
  88. void    disposeOffscreen(void);                        /* Disposes the memory used for the offscreen. */
  89.  
  90. int        randomInteger(int min, int max);            /* Returns a random integer. */
  91. int        randomSignInteger(int start,int end);        /* Returns a variation of randomInteger. */
  92. int        absInteger(int num);                        /* Returns the absolute value. */
  93. void    getRandomColor(long    *r,long *g,long *b);    /* Returns a random old QD gxColor. */
  94.  
  95. /*-----------------------------------------------------------------------------------*/
  96.  
  97. main()
  98. {
  99.     gxGraphicsClient     client;
  100.     
  101.     initMac();
  102.  
  103.     client = GXNewGraphicsClient( nil, 2000L * 1024, 0L );
  104.     
  105.     createWindow();
  106.     
  107.     createOffscreen();
  108.     initializeShapes();
  109.     
  110.     doEventLoop();
  111.     
  112.     disposeOffscreen();
  113.     GXDisposeGraphicsClient( client );
  114. }
  115.  
  116. /*-----------------------------------------------------------------------------------*/
  117.  
  118. void initMac()
  119. {
  120.     MaxApplZone();
  121.     MoreMasters (); MoreMasters (); MoreMasters (); MoreMasters ();
  122.  
  123.     InitGraf( &qd.thePort );
  124.     InitFonts();
  125.     InitWindows();
  126.     /***
  127.     InitMenus();
  128.     TEInit();
  129.     InitDialogs( nil );***/
  130.     InitCursor();
  131.     FlushEvents( 0, everyEvent );
  132.     
  133.     qd.randSeed = TickCount();
  134. }
  135.  
  136. /*-----------------------------------------------------------------------------------*/
  137.  
  138. void createWindow()
  139. {
  140.     Rect    rect;
  141.     
  142.     SetRect( &rect, kWinLeft, kWinTop, kWinLeft + kWinWidth, kWinTop + kWinHeight );
  143.     gWindow = NewCWindow( 0L, &rect, "\pOffscreen Animation", true, documentProc,
  144.                             (WindowPtr)-1L, true, 0L );                        
  145.     SetPort( gWindow );
  146.     SetDefaultViewPort( GXNewWindowViewPort( gWindow ) );
  147. }
  148.  
  149. /*-----------------------------------------------------------------------------------*/
  150.  
  151. void initializeShapes()
  152. {
  153.     int            i;
  154.     int            radius, minRadius, maxRadius;
  155.     long        red, green, blue;
  156.     float        brightnessFactor;
  157.     gxRectangle     bgRectData = { ff( 0 ), ff( 0 ), ff( kWinWidth ), ff( kWinHeight ) };    
  158.     gxRectangle     objectRectData;
  159.     
  160.     /******************************************************/
  161.     /* Initialize the background shape for the offscreen. */
  162.     /******************************************************/
  163.  
  164.     gTheBackground = GXNewRectangle( &bgRectData );
  165.     GXSetShapeTransform( gTheBackground, gOffscreen.xform );
  166.     SetShapeRGB( gTheBackground, 0, 0, 0 );
  167.  
  168.     /**************************************************/
  169.     /* Initialize the moving shapes in the offscreen. */
  170.     /**************************************************/
  171.     
  172.     for (i = 0; i < kMaxObjects; i++)
  173.     {
  174.         /***************************************/
  175.         /* Define the shape's movement offset. */
  176.         /***************************************/
  177.         
  178.         if (i < (2 * kMaxObjects) / 3)
  179.         {
  180.             minRadius = 1;
  181.             maxRadius = 3;
  182.         }
  183.         else if (i >= (2 * kMaxObjects) / 3 && i < (7 * kMaxObjects) / 8)
  184.         {
  185.             minRadius = 4;
  186.             maxRadius = 6;
  187.         }
  188.         else if (i >= (7 * kMaxObjects) / 8 && i < kMaxObjects)
  189.         {
  190.             minRadius = 7;
  191.             maxRadius = 10;
  192.         }
  193.             
  194.         gMovingObject[i].xdelta    = randomSignInteger( minRadius, maxRadius );
  195.         gMovingObject[i].ydelta    = randomSignInteger( minRadius, maxRadius );
  196.  
  197.         /****************************/
  198.         /* Define the shape's size. */
  199.         /****************************/
  200.         
  201.         if (absInteger( gMovingObject[i].xdelta ) >= absInteger( gMovingObject[i].ydelta ))
  202.             radius = absInteger( gMovingObject[i].xdelta );
  203.         else
  204.             radius = absInteger( gMovingObject[i].ydelta );
  205.             
  206.         objectRectData.left        = ff( randomInteger( 1, kWinWidth ) );
  207.         objectRectData.top        = ff( randomInteger( 1, kWinHeight ) );
  208.         objectRectData.right    = objectRectData.left + ff( radius );
  209.         objectRectData.bottom    = objectRectData.top + ff( radius );
  210.         
  211.         gMovingObject[i].shape    = GXNewRectangle( &objectRectData );
  212.         GXSetShapeTransform( gMovingObject[i].shape, gOffscreen.xform );
  213.  
  214.         /*****************************/
  215.         /* Define the shape's gxColor. */
  216.         /*****************************/
  217.         
  218.         brightnessFactor = (float)radius / 10.;
  219.         getRandomColor( &red, &green, &blue );
  220.                 
  221.         SetShapeRGB( gMovingObject[i].shape, red * brightnessFactor,
  222.                     green * brightnessFactor, blue * brightnessFactor );
  223.     }
  224. }
  225.  
  226. /*-----------------------------------------------------------------------------------*/
  227.  
  228. void createOffscreen()
  229. {
  230.     Rect        rect;
  231.     gxBitmap    bm;
  232.     gxShape        offscreenShape;
  233.  
  234.     rect = (*gWindow).portRect;
  235.     
  236.     bm.width        = rect.right - rect.left;
  237.     bm.height        = rect.bottom - rect.top;
  238.     bm.pixelSize    = 8;
  239.     bm.rowBytes        = 0;
  240.     bm.space        = gxIndexedSpace;
  241.     bm.set            = CTableToColorSet( GetCTable( 8 ) );
  242.     bm.profile        = nil;
  243.     bm.image        = nil;
  244.     
  245.     offscreenShape = GXNewBitmap( &bm, nil );
  246.     CreateOffscreen( &gOffscreen, offscreenShape );
  247. }
  248.  
  249. /*-----------------------------------------------------------------------------------*/
  250.  
  251. void updateOffscreen()
  252. {
  253.     int            i;
  254.     Fixed        xpos, ypos;
  255.     Fixed        xdelta, ydelta;
  256.     gxRectangle    bounds;
  257.     gxViewPort    savedViewPort;
  258.  
  259.     /**********************************************************/
  260.     /* Draw the background shape to erase the previous image. */
  261.     /**********************************************************/
  262.  
  263.     GXDrawShape( gTheBackground );
  264.  
  265.     /***************************************************/
  266.     /* Draw the moving objects in their new positions. */
  267.     /***************************************************/
  268.  
  269.     for (i = 0; i < kMaxObjects; i++)
  270.     {
  271.         GXDrawShape( gMovingObject[i].shape );
  272.         
  273.         GXGetShapeBounds( gMovingObject[i].shape, 0L, &bounds );
  274.         
  275.         xpos = bounds.left;
  276.         ypos = bounds.top;
  277.         
  278.         xdelta = ff( gMovingObject[i].xdelta / 2 );
  279.         ydelta = ff( gMovingObject[i].ydelta / 2 );
  280.         
  281.         /***************************************************/
  282.         /* If the object goes beyond the offscreen bounds, */
  283.         /*   make it go in the opposite direction.         */
  284.         /***************************************************/
  285.  
  286.         if (xpos + xdelta >= ff( kWinWidth ) || xpos + xdelta <= ff( 0 ))
  287.             gMovingObject[i].xdelta = -gMovingObject[i].xdelta;
  288.         
  289.         if (ypos + ydelta >= ff( kWinHeight ) || ypos + ydelta <= ff( 0 ))
  290.             gMovingObject[i].ydelta = -gMovingObject[i].ydelta;
  291.     
  292.         GXMoveShapeTo( gMovingObject[i].shape, xpos + xdelta, ypos + ydelta );
  293.     }
  294. }
  295.  
  296. /*-----------------------------------------------------------------------------------*/
  297.  
  298. void disposeOffscreen()
  299. {
  300.     DisposeOffscreen( &gOffscreen );
  301. }
  302.  
  303. /*-----------------------------------------------------------------------------------*/
  304.  
  305. void drawOffscreen()
  306. {
  307.     GXDrawShape( gOffscreen.draw );
  308. }
  309.  
  310. /*-----------------------------------------------------------------------------------*/
  311.  
  312. void doEventLoop()
  313. {
  314.     EventRecord     event;
  315.     WindowPtr       window;
  316.     short           clickArea;
  317.     Rect            screenRect;
  318.     long            ticks = 0;
  319.     
  320.     for (;;)
  321.     {
  322.         /************************************************/
  323.         /* Update the offscreen once every 1/30 second. */
  324.         /************************************************/
  325.  
  326.         if (TickCount() - ticks > 2)
  327.         {
  328.             updateOffscreen();
  329.             drawOffscreen();
  330.             ticks = TickCount();
  331.         }
  332.  
  333.         /***************************/
  334.         /* Handle incoming events. */
  335.         /***************************/
  336.         
  337.         if (WaitNextEvent( everyEvent, &event, 0, nil ))
  338.         {
  339.             if (event.what == mouseDown)
  340.             {
  341.                 clickArea = FindWindow( event.where, &window );
  342.                 
  343.                 if (clickArea == inDrag)
  344.                 {
  345.                     screenRect = (**GetGrayRgn()).rgnBBox;
  346.                     DragWindow( window, event.where, &screenRect );
  347.                 }
  348.                 else if (clickArea == inContent)
  349.                 {
  350.                     if (window != FrontWindow())
  351.                         SelectWindow( window );
  352.                 }
  353.                 else if (clickArea == inGoAway)
  354.                     if (TrackGoAway( window, event.where ))
  355.                         return;
  356.             }
  357.             else if (event.what == updateEvt)
  358.             {
  359.                 window = (WindowPtr)event.message;    
  360.                 SetPort( window );
  361.                 
  362.                 BeginUpdate( window );
  363.                 drawOffscreen();
  364.                 EndUpdate( window );
  365.             }
  366.         }
  367.     }
  368. }
  369.  
  370. /*-----------------------------------------------------------------------------------*/
  371.  
  372. int absInteger( num )
  373. int        num;
  374. {
  375.     int        absolute;
  376.     
  377.     absolute = num;
  378.     
  379.     if (absolute < 0)
  380.         absolute = -absolute;
  381.         
  382.     return absolute;
  383. }
  384.  
  385. /*-----------------------------------------------------------------------------------*/
  386.  
  387. int    randomInteger( min, max )
  388. int        min, max;
  389. {
  390.     long     randomNum;
  391.  
  392.     randomNum = Random();
  393.         
  394.     if (min >= 0 && max >= 0)
  395.     {
  396.         if (randomNum < 0)
  397.             randomNum = -randomNum;
  398.     }
  399.     
  400.     randomNum = ((randomNum * (max - min)) / 32767) + min;
  401.     
  402.     return randomNum;
  403. }
  404.  
  405. /*-----------------------------------------------------------------------------------*/
  406.  
  407. int    randomSignInteger( start, end )
  408. int        start, end;
  409. {
  410.     long    randomNum;
  411.     int        sign = 1;
  412.         
  413.     if ((randomNum = Random()) < 0)
  414.     {
  415.         randomNum = -randomNum;
  416.         sign = -1;
  417.     }
  418.  
  419.     randomNum = (((randomNum * (end - start)) / 32767) + start) * sign;
  420.             
  421.     return randomNum;
  422. }
  423.  
  424. /*-----------------------------------------------------------------------------------*/
  425.  
  426. void getRandomColor( r, g, b )
  427. long    *r, *g, *b;
  428. {
  429.     long    randomNum;
  430.     int        choice;
  431.     
  432.     randomNum = Random();
  433.     choice = absInteger( (randomNum * 7) / 32767 );
  434.     
  435.     if (choice == 0)                /*** red ***/
  436.     {
  437.         *r = 0xffff;
  438.         *g = 0;
  439.         *b = 0;
  440.     }
  441.     else if (choice == 1)            /*** green ***/
  442.     {
  443.         *r = 0;
  444.         *g = 0xffff;
  445.         *b = 0;
  446.     }
  447.     else if (choice == 2)            /*** blue ***/
  448.     {
  449.         *r = 0;
  450.         *g = 0;
  451.         *b = 0xffff;
  452.     }
  453.     else if (choice == 3)            /*** yellow ***/
  454.     {
  455.         *r = 0xffff;
  456.         *g = 0xffff;
  457.         *b = 0;
  458.     }
  459.     else if (choice == 4)            /*** magenta ***/
  460.     {
  461.         *r = 0xffff;
  462.         *g = 0;
  463.         *b = 0xffff;
  464.     }
  465.     else if (choice == 5)            /*** cyan ***/
  466.     {
  467.         *r = 0;
  468.         *g = 0xffff;
  469.         *b = 0xffff;
  470.     }
  471.     else if (choice == 6)            /*** white ***/
  472.     {
  473.         *r = 0xffff;
  474.         *g = 0xffff;
  475.         *b = 0xffff;
  476.     }
  477. }